import express from 'express'
import {
    addMusic, getAllMusic, deleteMusic, getMusicById, getRandomMusic, getMusicByPackageId,
    getRandomMusicByPackageId
} from './db/db_music.js'
import {addMusicPackage,getAllMusicPackages,deleteMusicPackage,getMusicPackageById} from './db/db_music_package.js'
import {getAllTemplates,getTemplateById,addTemplate,updateTemplate,deleteTemplate} from './db/db_template.js'
import {getAllUser,addUser,login,updateUser,getUserById,deleteUser} from './db/db_user.js'
import {getAllVoices,getVoiceById,addVoice,updateVoice,deleteVoice} from './db/db_voice.js'
import coze from './coze.js'
import multer from 'multer'
import path from 'path'
import fs from 'fs'
const app = express()
const port = 3000
import cors from 'cors'
app.use(cors()) // 允许所有来源跨域
app.use(express.json())

app.get('/', (req, res) => {
    res.send('Hello World!')
})

// Ensure downloads directory exists
const downloadsDir = path.resolve('downloads')
if (!fs.existsSync(downloadsDir)) {
    fs.mkdirSync(downloadsDir)
}

// Set up multer for file uploads
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, downloadsDir)
    },
    filename: function (req, file, cb) {
        const ext = path.extname(file.originalname)
        cb(null, Date.now() + '-' + file.fieldname + ext)
    }
})
const upload = multer({ storage: storage })
app.use('/downloads', express.static(downloadsDir)) // 增加 downloads 静态资源路由

app.post('/addMusic', upload.single('musicFile'), async (req, res) => {
    if (!req.file) {
        return res.status(400).send('No file uploaded.')
    }

    const fileUrl = `/downloads/${req.file.filename}`
    console.log(req.file.filename)
    console.log(req.body.name)
    console.log(req.body.package_id)
    const ID = await addMusic({
        name: req.body.name,
        url: fileUrl,
        package_id: req.body.package_id,
    })
    const domain = req.protocol + '://' + req.get('host')
    return res.send({
        "code": 0,
        "msg": "Music added successfully",
        "data": {
            "name": req.body.name,
            "url": domain + fileUrl,
            "package_id": req.body.package_id,
            "id": ID
        }
    })
})

app.get('/getAllMusic', async (req, res) => {
    try {
        const musicList = await getAllMusic()
        const domain = req.protocol + '://' + req.get('host')

        for (const music of musicList) {
            if (music.url && !music.url.startsWith('http')) {
                music.url = domain + music.url;
            }
            if (music.package_id) {
                const music_package_obj = await getMusicPackageById(music.package_id);
                music.package_name = music_package_obj?.name || '';
            } else {
                music.package_name = "";
            }
        }
        res.json(musicList)
    } catch (error) {
        console.error('Error fetching music:', error)
        res.status(500).send('Error fetching music')
    }
})

app.get('/getRandomMusic', async (req, res) => {
    try {
        const music = await getRandomMusic()
        const domain = req.protocol + '://' + req.get('host')
        if (music.url && !music.url.startsWith('http')) {
            music.url = domain + music.url
        }
        res.json(music)
    } catch (error) {
        console.error('Error fetching music:', error)
        res.status(500).send('Error fetching music')
    }
})

app.get('/deleteMusic/:id', async (req, res) => {
    const id = req.params.id
    try {
        const music = await getMusicById(id)
        if (!music) {
            return res.status(404).json({ code: -1, msg: 'Music not found' })
        }
        // 提取文件名
        const fileName = path.basename(music.url)
        const result = await deleteMusic(id)
        if (result) {
            console.log("删除本地音乐文件", fileName)
            fs.unlinkSync(path.join(downloadsDir, fileName)) // 删除本地文件
            res.json({ code: 0, msg: 'Music deleted successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Music not found' })
        }
    } catch (error) {
        console.error('Error deleting music:', error)
        res.status(500).json({ code: 1, msg: 'Error deleting music' })
    }
})
app.get('/getAllTemplates', async (req, res) => {
    try {
        const templates = await getAllTemplates()
        for (const template of templates) {
            if (template.package_id) {
                const template_package_obj = await getMusicPackageById(template.package_id);
                template.package_name = template_package_obj?.name || '';
            } else {
                template.package_name = "";
            }
        }
        res.json(templates)
    } catch (error) {
        console.error('Error fetching templates:', error)
        res.status(500).send('Error fetching templates')
    }
} )

app.post('/addTemplate', async (req, res) => {
    const { name, detail, package_id } = req.body
    if (!name || !detail || !package_id) {
        return res.status(400).json({ code: -1, msg: 'Name and detail and package_id are required' })
    }
    try {
        const id = await addTemplate({ name, detail, package_id })
        res.json({ code: 0, msg: 'Template added successfully', data: { id , name , detail} })
    } catch (error) {
        console.error('Error adding template:', error)
        res.status(500).json({ code: -1, msg: 'Error adding template' })
    }
})

app.post('/updateTemplate', async (req, res) => {
    const { id, name, detail, package_id } = req.body
    if (!id || !name || !detail || !package_id) {
        return res.status(400).json({ code: -1, msg: 'ID, name and detail are required' })
    }
    try {
        const result = await updateTemplate(id, { name, detail,package_id })
        if (result) {
            res.json({ code: 0, msg: 'Template updated successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Template not found' })
        }
    } catch (error) {
        console.error('Error updating template:', error)
        res.status(500).json({ code: -1, msg: 'Error updating template' })
    }
})

app.get('/deleteTemplate/:id', async (req, res) => {
    const id = req.params.id
    try {
        const template = await getTemplateById(id)
        if (!template) {
            return res.status(404).json({ code: -1, msg: 'Template not found' })
        }
        const result = await deleteTemplate(id)
        if (result) {
            res.json({ code: 0, msg: 'Template deleted successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Template not found' })
        }
    } catch (error) {
        console.error('Error deleting template:', error)
        res.status(500).json({ code: 1, msg: 'Error deleting template' })
    }
})

app.get('/coze-auth-callback', coze.callback)
//下载音色
app.get('/getVoice', async (req, res) => {
    let {workflow_id} = req.query
    if (!workflow_id) {
        return res.status(400).json({ code: -1, msg: 'workflow_id is required' })
    }
    const data = await coze.voice1(workflow_id)
    res.json({ code: 0, msg: 'success', data: JSON.parse(data.content) })
})
//音色列表
app.get('/voiceList', async (req, res) => {
    try {
        const voiceList = await getAllVoices()
        res.json({ code: 0, msg: 'success', data: voiceList})
        // res.json(voiceList)
    } catch (error) {
        console.error('Error fetching Voices:', error)
        res.status(500).send('Error fetching Voices')
    }
    // res.json({ code: 0, msg: 'success', data: [
    //   {'workflow_id': '7534665748078936091', 'name': '湘妹子配音'},
    //   {'workflow_id': '7535880106314612755', 'name': '台妹配音'}
    // ]})
})

app.post('/addVoice', async (req, res) => {
    const { name, workflow_id } = req.body
    if (!name || !workflow_id) {
        return res.status(400).json({ code: -1, msg: 'Name and workflow_id are required' })
    }
    try {
        const id = await addVoice({ name, workflow_id })
        res.json({ code: 0, msg: 'Voice added successfully', data: { id , name , workflow_id} })
    } catch (error) {
        console.error('Error adding voice:', error)
        res.status(500).json({ code: -1, msg: 'Error adding voice' })
    }
})

app.post('/updateVoice', async (req, res) => {
    const { id, name, workflow_id } = req.body
    if (!id || !name || !workflow_id) {
        return res.status(400).json({ code: -1, msg: 'ID, name, workflow_id are required' })
    }
    try {
        const result = await updateVoice(id, { name, workflow_id })
        if (result) {
            res.json({ code: 0, msg: 'Voice updated successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Voice not found' })
        }
    } catch (error) {
        console.error('Error updating Voice:', error)
        res.status(500).json({ code: -1, msg: 'Error updating Voice' })
    }
})

app.get('/deleteVoice/:id', async (req, res) => {
    const id = req.params.id
    try {
        const user = await getVoiceById(id)
        if (!user) {
            return res.status(404).json({ code: -1, msg: 'Voice not found' })
        }
        const result = await deleteVoice(id)
        if (result) {
            res.json({ code: 0, msg: 'Voice deleted successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Voice not found' })
        }
    } catch (error) {
        console.error('Error deleting user:', error)
        res.status(500).json({ code: 1, msg: 'Error deleting user' })
    }
})



app.get('/getAllUsers', async (req, res) => {
    try {
        const userList = await getAllUser()
        res.json(userList)
    } catch (error) {
        console.error('Error fetching users:', error)
        res.status(500).send('Error fetching users')
    }
})

app.post('/addUser', async (req, res) => {
    const { name, pass, times } = req.body
    console.log(req.body)
    if (!name || !pass) {
        return res.status(400).json({ code: -1, msg: 'Name and password are required' })
    }
    try {
        const id = await addUser({ name, pass, times })
        res.json({ code: 0, msg: 'User added successfully', data: { id , name , pass, times} })
    } catch (error) {
        console.error('Error adding user:', error)
        res.status(500).json({ code: -1, msg: 'Error adding user' })
    }
})

app.post('/login', async (req, res) => {
    const { name, pass } = req.body
    if (!name || !pass) {
        return res.status(400).json({ code: -1, msg: 'Name and password are required' })
    }
    try {
        const user = await login(name, pass)
        if (user) {
            res.json({ code: 0, msg: 'Login successful', data: user })
        } else {
            res.status(401).json({ code: -1, msg: 'Invalid username or password' })
        }
    } catch (error) {
        console.error('Error logging in:', error)
        res.status(500).json({ code: -1, msg: 'Error logging in' })
    }
})

app.get('/deleteUser/:id', async (req, res) => {
    const id = req.params.id
    try {
        const user = await getUserById(id)
        if (!user) {
            return res.status(404).json({ code: -1, msg: 'User not found' })
        }
        const result = await deleteUser(id)
        if (result) {
            res.json({ code: 0, msg: 'User deleted successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'User not found' })
        }
    } catch (error) {
        console.error('Error deleting user:', error)
        res.status(500).json({ code: 1, msg: 'Error deleting user' })
    }
})

app.post('/updateUser', async (req, res) => {
    const { id, name, pass, times } = req.body
    if (!id || !name || !pass || !times) {
        return res.status(400).json({ code: -1, msg: 'ID, name, pass and times are required' })
    }
    try {
        const result = await updateUser(id, { name, pass, times })
        if (result) {
            res.json({ code: 0, msg: 'User updated successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'User not found' })
        }
    } catch (error) {
        console.error('Error updating user:', error)
        res.status(500).json({ code: -1, msg: 'Error updating user' })
    }
})

app.get("/useCredit", async (req, res) => {
    const { userId } = req.query
    if (!userId) {
        return res.status(400).json({ code: -1, msg: 'userId is required' })
    }
    try {
        const user = await getUserById(userId)
        if (!user) {
            return res.status(404).json({ code: -1, msg: 'User not found' })
        }
        if (user.times <= 0) {
            return res.status(403).json({ code: -1, msg: 'Insufficient credits' })
        }
        await updateUser(userId, { times: user.times - 1 })
        res.json({ code: 0, msg: 'Credit used successfully', data: { remainingCredits: user.times - 1 } })
    } catch (error) {
        console.error('Error using credit:', error)
        res.status(500).json({ code: -1, msg: 'Error using credit' })
    }
})

// 音乐包列表
app.get('/getAllMusicPackages', async (req, res) => {
    try {
        const musicPackageList = await getAllMusicPackages()
        // const domain = req.protocol + '://' + req.get('host')
        // musicList.forEach(music => {
        //     if (music.url && !music.url.startsWith('http')) {
        //         music.url = domain + music.url
        //     }
        // })
        res.json(musicPackageList)
    } catch (error) {
        console.error('Error fetching music:', error)
        res.status(500).send('Error fetching music')
    }
})

// 新增音乐包
app.post('/addMusicPackage', async (req, res) => {
    const ID = await addMusicPackage({
        name: req.body.name,
        description: req.body.description
    })
    // const domain = req.protocol + '://' + req.get('host')
    return res.send({
        "code": 0,
        "msg": "Music package added successfully",
        "data": {
            "name": req.body.name,
            "description": req.body.description,
            "id": ID
        }
    })
})

// 删除音乐包
app.get('/deleteMusicPackage/:id', async (req, res) => {
    const id = req.params.id
    try {
        const music_package = await getMusicPackageById(id)
        if (!music_package) {
            return res.status(404).json({ code: -1, msg: 'Music Package not found' })
        }
        // 提取文件名
        // const fileName = path.basename(music.url)
        const result = await deleteMusicPackage(id)
        if (result) {
            // console.log("删除本地音乐文件", fileName)
            // fs.unlinkSync(path.join(downloadsDir, fileName)) // 删除本地文件
            res.json({ code: 0, msg: 'Music Package deleted successfully' })
        } else {
            res.status(404).json({ code: -1, msg: 'Music package not found' })
        }
    } catch (error) {
        console.error('Error deleting music Package:', error)
        res.status(500).json({ code: 1, msg: 'Error deleting music Package' })
    }
})


app.get('/getAllMusicByPackageId/:id', async (req, res) => {
    const package_id = req.params.id
    try {
        const musicList = await getMusicByPackageId(package_id)
        const domain = req.protocol + '://' + req.get('host')

        for (const music of musicList) {
            if (music.url && !music.url.startsWith('http')) {
                music.url = domain + music.url;
            }
            if (music.package_id) {
                const music_package_obj = await getMusicPackageById(music.package_id);
                music.package_name = music_package_obj?.name || '';
            } else {
                music.package_name = "";
            }
        }
        res.json(musicList)
    } catch (error) {
        console.error('Error fetching music:', error)
        res.status(500).send('Error fetching music')
    }
})


app.get('/getRandomMusicByPackageId/:package_id', async (req, res) => {
    const package_id = req.params.package_id
    try {
        const music = await getRandomMusicByPackageId(package_id)
        const domain = req.protocol + '://' + req.get('host')
        if (music.url && !music.url.startsWith('http')) {
            music.url = domain + music.url
        }
        res.json(music)
    } catch (error) {
        console.error('Error fetching music:', error)
        res.status(500).send('Error fetching music')
    }
})


app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`)
})